//
//  TestClassC.m
//  MessageForwarding
//
//  Created by 刘博 on 15/4/29.
//  Copyright (c) 2015年 AutoNavi. All rights reserved.
//

#import "TestClassC.h"
#import "TestClassB.h"
#import <objc/runtime.h>

@interface TestClassC ()
{
    TestClassB *_internalClassB;
}

@end

@implementation TestClassC

- (instancetype)init
{
    if (self = [super init])
    {
        _internalClassB = [[TestClassB alloc] init];
    }
    return self;
}

#pragma mark - Step 1: resolveMethod

+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSLog(@"%s", __func__);
    
    return [super resolveInstanceMethod:sel];
}

+ (BOOL)resolveClassMethod:(SEL)sel
{
    NSLog(@"%s", __func__);
    
    return [super resolveClassMethod:sel];
}

#pragma mark - Step 2: forwardingTargetForSelector

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    NSLog(@"%s", __func__);
    
    return [super forwardingTargetForSelector:aSelector];
}

#pragma mark - Step 3: forwardInvocation

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    NSLog(@"%s", __func__);
    
    SEL anSEL = anInvocation.selector;
    
    if ([_internalClassB respondsToSelector:anSEL])
    {
        [anInvocation invokeWithTarget:_internalClassB];
    }
    else
    {
        [self doesNotRecognizeSelector:anSEL];
    }
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
    NSLog(@"%s", __func__);
    
    if ([super respondsToSelector:aSelector])
    {
        return YES;
    }
    else
    {
        return [_internalClassB respondsToSelector:aSelector];
    }
}

+ (BOOL)instancesRespondToSelector:(SEL)aSelector
{
    NSLog(@"%s", __func__);
    
    if ([super instancesRespondToSelector:aSelector])
    {
        return YES;
    }
    else
    {
        return [TestClassB instancesRespondToSelector:aSelector];
    }
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSLog(@"%s", __func__);
    
    NSMethodSignature *aSig = [super methodSignatureForSelector:aSelector];
    
    if (aSig == nil)
    {
        aSig = [_internalClassB methodSignatureForSelector:aSelector];
    }
    
    return aSig;
}

@end
